package cn.com.idmy.cloud;

import cn.com.idmy.base.config.DefaultConfig;
import cn.com.idmy.base.util.AppUtil;
import cn.com.idmy.cloud.mask.Masks;
import cn.com.idmy.cloud.util.IpUtil;
import cn.com.idmy.cloud.util.WebUtil;
import com.alibaba.fastjson2.JSON;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.dromara.hutool.core.text.StrUtil;
import org.jetbrains.annotations.NotNull;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

@Slf4j
@Order(0)
public class GlobalFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain chain) throws ServletException, IOException {
        try {
            if (!"true".equals(request.getHeader(DefaultConfig.corsDisabledHeaderName))) {
                String allowOrigin = WebUtil.getAllowOrigin(DefaultConfig.accessControlAllowOrigin);
                response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, allowOrigin);
                response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, String.valueOf(DefaultConfig.accessControlAllowCredentials));
                if (HttpMethod.OPTIONS.name().equalsIgnoreCase(request.getMethod())) {
                    response.setHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, String.join(", ", DefaultConfig.accessControlRequestMethods));
                    response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, String.join(", ", DefaultConfig.accessControlAllowHeaders));
                    response.setHeader(HttpHeaders.ACCESS_CONTROL_MAX_AGE, String.valueOf(DefaultConfig.accessControlMaxAge));
                    response.setStatus(HttpServletResponse.SC_OK);
                    return;
                } else {
                    if (DefaultConfig.accessControlExposeHeaders.length > 0) {
                        response.setHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, String.join(", ", DefaultConfig.accessControlExposeHeaders));
                    }
                }
            }
            if (log.isDebugEnabled() && AppUtil.isLocal()) {
                var ip = IpUtil.getIpv4(request);
                var uri = request.getRequestURI();
                var map = request.getParameterMap();
                var names = request.getHeaderNames();
                var headers = new StringBuilder();
                while (names.hasMoreElements()) {
                    headers.append(names.nextElement());
                    headers.append(":");
                    headers.append(request.getHeader(names.nextElement()));
                    headers.append(";");
                }
                log.debug("ip:{}, 地址:{}, 方法:{}, 头:{}, 参数:{},", ip, uri, request.getMethod(), headers, JSON.toJSONString(map));
            }

            if (StrUtil.equalsIgnoreCase(request.getMethod(), HttpMethod.OPTIONS.name())) {
                WebUtil.write(response, "");
            } else {
                chain.doFilter(request, response);
            }
        } finally {
            Masks.clear();
        }
    }
}
